/*
Abstract:
  Logging declaration

Last changed:
  $Id: logging.h 82 2009-12-08 20:53:44Z vitamin.caig $

Author:
  (C) Vitamin/CAIG/2001

  This file is the part of Textator project
*/

#ifndef __LOGGING_H_DEFINED__
#define __LOGGING_H_DEFINED__

#include <types.h>

struct Error;

namespace Log
{
  enum Level
  {
    DEFAULT = 0,
    VERBOSE,
    DEBUG
  };

  void SetLogLevel(Level level);
  //true if may log message with specified level
  bool CheckLogLevel(Level level);

  //unconditional message
  void DoMessage(const String& msg);

  inline void Message(const String& msg, Level level = VERBOSE)
  {
    if (CheckLogLevel(level))
    {
      DoMessage(msg);
    }
  }

  template<class P>
  inline void Message(const String& fmt, const P& p, Level level = VERBOSE)
  {
    if (CheckLogLevel(level))
    {
      DoMessage(StringFormatter::Process(fmt, p));
    }
  }

  template<class P1, class P2>
  inline void Message(const String& fmt, const P1& p1, const P2& p2, Level level = VERBOSE)
  {
    if (CheckLogLevel(level))
    {
      DoMessage(StringFormatter::Process(fmt, p1, p2));
    }
  }

  template<class P1, class P2, class P3>
  inline void Message(const String& fmt, const P1& p1, const P2& p2, const P3& p3, Level level = VERBOSE)
  {
    if (CheckLogLevel(level))
    {
      DoMessage(StringFormatter::Process(fmt, p1, p2, p3));
    }
  }

  template<class P1, class P2, class P3, class P4>
  inline void Message(const String& fmt, const P1& p1, const P2& p2, const P3& p3, const P4& p4, Level level = VERBOSE)
  {
    if (CheckLogLevel(level))
    {
      DoMessage(StringFormatter::Process(fmt, p1, p2, p3, p4));
    }
  }
  
  template<class P1, class P2, class P3, class P4, class P5>
  inline void Message(const String& fmt, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, Level level = VERBOSE)
  {
    if (CheckLogLevel(level))
    {
      DoMessage(StringFormatter::Process(fmt, p1, p2, p3, p4, p5));
    }
  }

  template<class P1>
  inline void Debug(const char* fmt, const P1& p1)
  {
    if (CheckLogLevel(DEBUG))
    {
      DoMessage(StringFormatter::Process(FromStdString(fmt), p1));
    }
  }

  template<class P1, class P2>
  inline void Debug(const char* fmt, const P1& p1, const P2& p2)
  {
    if (CheckLogLevel(DEBUG))
    {
      DoMessage(StringFormatter::Process(FromStdString(fmt), p1, p2));
    }
  }

  template<class P1, class P2, class P3>
  inline void Debug(const char* fmt, const P1& p1, const P2& p2, const P3& p3)
  {
    if (CheckLogLevel(DEBUG))
    {
      DoMessage(StringFormatter::Process(FromStdString(fmt), p1, p2, p3));
    }
  }

  template<class P1, class P2, class P3, class P4>
  inline void Debug(const char* fmt, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
  {
    if (CheckLogLevel(DEBUG))
    {
      DoMessage(StringFormatter::Process(FromStdString(fmt), p1, p2, p3, p4));
    }
  }

  void ProgressMessage(std::size_t current, std::size_t total, Level level = VERBOSE);

  void ErrorMessage(const Error& err);
}

#endif //__LOGGING_H_DEFINED__
